package com.zenithmind.version.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.result.Result;
import com.zenithmind.version.pojo.dto.FileVersionCreateDTO;
import com.zenithmind.version.pojo.query.FileVersionQueryDTO;
import com.zenithmind.version.pojo.vo.FileVersionVO;
import com.zenithmind.version.service.FileVersionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 文件版本管理控制器
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Tag(name = "文件版本管理", description = "文件版本管理相关接口")
@RestController
@RequestMapping("/api/v1/file-versions")
@RequiredArgsConstructor
public class FileVersionController {

    private final FileVersionService fileVersionService;

    @Operation(summary = "创建文件版本", description = "创建新的文件版本")
    @PostMapping
    public Result<FileVersionVO> createFileVersion(@Valid @RequestBody FileVersionCreateDTO createDTO) {
        FileVersionVO fileVersion = fileVersionService.createFileVersion(createDTO);
        return Result.success(fileVersion);
    }

    @Operation(summary = "分页查询文件版本", description = "分页查询文件版本列表")
    @PostMapping("/page")
    public Result<IPage<FileVersionVO>> getFileVersionPage(@Valid @RequestBody FileVersionQueryDTO queryDTO) {
        IPage<FileVersionVO> page = fileVersionService.getFileVersionPage(queryDTO);
        return Result.success(page);
    }

    @Operation(summary = "获取文件版本详情", description = "获取文件版本详细信息")
    @GetMapping("/{id}")
    public Result<FileVersionVO> getFileVersionDetail(@Parameter(description = "版本ID") @PathVariable String id) {
        FileVersionVO fileVersion = fileVersionService.getFileVersionDetail(id);
        return Result.success(fileVersion);
    }

    @Operation(summary = "获取文件版本历史", description = "获取文件的版本历史")
    @GetMapping("/history")
    public Result<List<FileVersionVO>> getFileVersionHistory(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "文件路径") @RequestParam String filePath,
            @Parameter(description = "分支名称") @RequestParam String branchName,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "50") Integer limit) {
        List<FileVersionVO> versions = fileVersionService.getFileVersionHistory(repositoryId, filePath, branchName, limit);
        return Result.success(versions);
    }

    @Operation(summary = "获取当前文件版本", description = "获取文件的当前版本")
    @GetMapping("/current")
    public Result<FileVersionVO> getCurrentFileVersion(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "文件路径") @RequestParam String filePath,
            @Parameter(description = "分支名称") @RequestParam String branchName) {
        FileVersionVO fileVersion = fileVersionService.getCurrentFileVersion(repositoryId, filePath, branchName);
        return Result.success(fileVersion);
    }

    @Operation(summary = "获取提交文件", description = "获取提交中的文件列表")
    @GetMapping("/commit/{commitId}")
    public Result<List<FileVersionVO>> getCommitFiles(@Parameter(description = "提交ID") @PathVariable String commitId) {
        List<FileVersionVO> files = fileVersionService.getCommitFiles(commitId);
        return Result.success(files);
    }

    @Operation(summary = "获取分支文件", description = "获取分支中的文件列表")
    @GetMapping("/branch")
    public Result<List<FileVersionVO>> getBranchFiles(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "分支名称") @RequestParam String branchName,
            @Parameter(description = "目录路径") @RequestParam(required = false) String directory) {
        List<FileVersionVO> files = fileVersionService.getBranchFiles(repositoryId, branchName, directory);
        return Result.success(files);
    }

    @Operation(summary = "比较文件版本", description = "比较两个文件版本的差异")
    @GetMapping("/compare")
    public Result<Object> compareFileVersions(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "文件路径") @RequestParam String filePath,
            @Parameter(description = "源版本") @RequestParam String fromVersion,
            @Parameter(description = "目标版本") @RequestParam String toVersion) {
        Object differences = fileVersionService.compareFileVersions(repositoryId, filePath, fromVersion, toVersion);
        return Result.success(differences);
    }

    @Operation(summary = "获取文件内容", description = "获取文件版本的内容")
    @GetMapping("/{id}/content")
    public Result<String> getFileContent(@Parameter(description = "版本ID") @PathVariable String id) {
        String content = fileVersionService.getFileContent(id);
        return Result.success(content);
    }

    @Operation(summary = "搜索文件", description = "根据关键词搜索文件")
    @GetMapping("/search")
    public Result<List<FileVersionVO>> searchFiles(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "关键词") @RequestParam String keyword,
            @Parameter(description = "分支名称") @RequestParam(required = false) String branchName,
            @Parameter(description = "文件类型") @RequestParam(required = false) String fileType,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "20") Integer limit) {
        List<FileVersionVO> files = fileVersionService.searchFiles(repositoryId, keyword, branchName, fileType, limit);
        return Result.success(files);
    }

    @Operation(summary = "获取文件统计", description = "获取文件统计信息")
    @GetMapping("/statistics")
    public Result<Object> getFileStatistics(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "文件路径") @RequestParam String filePath) {
        Object statistics = fileVersionService.getFileStatistics(repositoryId, filePath);
        return Result.success(statistics);
    }

    @Operation(summary = "恢复文件版本", description = "恢复文件到指定版本")
    @PostMapping("/restore")
    public Result<FileVersionVO> restoreFileVersion(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "文件路径") @RequestParam String filePath,
            @Parameter(description = "分支名称") @RequestParam String branchName,
            @Parameter(description = "目标版本") @RequestParam String targetVersion) {
        String userId = UserContext.getUserId();
        FileVersionVO fileVersion = fileVersionService.restoreFileVersion(repositoryId, filePath, branchName, targetVersion, userId);
        return Result.success(fileVersion);
    }

    @Operation(summary = "复制文件到分支", description = "复制文件到其他分支")
    @PostMapping("/copy")
    public Result<FileVersionVO> copyFileToBranch(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "文件路径") @RequestParam String filePath,
            @Parameter(description = "源分支") @RequestParam String sourceBranch,
            @Parameter(description = "目标分支") @RequestParam String targetBranch) {
        String userId = UserContext.getUserId();
        FileVersionVO fileVersion = fileVersionService.copyFileToBranch(repositoryId, filePath, sourceBranch, targetBranch, userId);
        return Result.success(fileVersion);
    }

    @Operation(summary = "批量删除文件版本", description = "批量删除文件版本")
    @DeleteMapping("/batch")
    public Result<Boolean> batchDeleteFileVersions(@RequestBody List<String> versionIds) {
        Boolean result = fileVersionService.batchDeleteFileVersions(versionIds);
        return Result.success(result);
    }

    @Operation(summary = "获取文件变更统计", description = "获取文件变更统计")
    @GetMapping("/change-statistics")
    public Result<Object> getFileChangeStatistics(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "开始时间") @RequestParam String startTime,
            @Parameter(description = "结束时间") @RequestParam String endTime) {
        Object statistics = fileVersionService.getFileChangeStatistics(repositoryId, startTime, endTime);
        return Result.success(statistics);
    }

    @Operation(summary = "获取热门文件", description = "获取热门文件列表")
    @GetMapping("/hot")
    public Result<List<Object>> getHotFiles(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "限制数量") @RequestParam(defaultValue = "10") Integer limit) {
        List<Object> files = fileVersionService.getHotFiles(repositoryId, limit);
        return Result.success(files);
    }

    @Operation(summary = "获取文件目录树", description = "获取文件目录树结构")
    @GetMapping("/tree")
    public Result<Object> getFileTree(
            @Parameter(description = "仓库ID") @RequestParam String repositoryId,
            @Parameter(description = "分支名称") @RequestParam String branchName,
            @Parameter(description = "路径") @RequestParam(required = false) String path) {
        Object tree = fileVersionService.getFileTree(repositoryId, branchName, path);
        return Result.success(tree);
    }

    @Operation(summary = "下载文件版本", description = "下载指定版本的文件")
    @GetMapping("/{id}/download")
    public ResponseEntity<byte[]> downloadFileVersion(@Parameter(description = "版本ID") @PathVariable String id) {
        String userId = UserContext.getUserId();
        byte[] fileData = fileVersionService.downloadFileVersion(id, userId);
        
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"file\"")
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(fileData);
    }

    @Operation(summary = "预览文件", description = "预览文件内容")
    @GetMapping("/{id}/preview")
    public Result<Object> previewFile(@Parameter(description = "版本ID") @PathVariable String id) {
        String userId = UserContext.getUserId();
        Object preview = fileVersionService.previewFile(id, userId);
        return Result.success(preview);
    }
}
